package net.freestu.sola.web.spider.urlfilter;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;

import net.freestu.sola.web.util.MyLogger;

/**
 * @author 秋刀鱼的滋味
 * 这个函数是通过判断报头的contenttype的信息来判定是否是网页的形式。过滤掉不是text/html的所有url.
 * 这个类突然有个额外的收获，这里可以在提取链接的时候对链接是否可以进行链接进行了过滤。
 * 不过该方法有一个弊端，就是这个地方的增加了对网络的连接，程序的运行速度降低了，但如果将后面下载页面时判断链接正确性
 * 综上考虑时，这个地方的效率能够抵消。效率都不会差太多。这个类应该用上。
 */
public class ContentTypeFilter extends FilterDecorator {

	public ContentTypeFilter(LinkFilter linkfilter){
		
		super(linkfilter);//在抽象类中进行构造对象。
		
	}
	
	//这个函数的质量有点高。复用性非常好。
	public void setState(){//检测状态。对LinkFilter的状态进行设置。这个貌似可以设置成private
		
		String str=linkfilter.getContent();//获取URL。
		int state=linkfilter.getState();//获取状态。
		
		
		if(state==URLFORBID){//如果不是不能通过的。
			
			linkfilter.setState(URLFORBID);
		}
		
		
		if(state==URLSTOP){//如果是处于暂停状态的。
			
			int temp=judgeState(str);
			linkfilter.setState(temp);
		}
		
		
		if(state==URLPASS){//如果是处于通过状态。
			
			//--------------9.24修改----------
			//int temp=judgeState(str);//按照逻辑来判定。
			//linkfilter.setState(temp);//
			//------------------------------
			
		   //这个类不应该有至高无上的权利，不能连接当然不能进行下载队列进行处理的啊!!
		   //URLPASS应该是至高无上的通行证。
			int temp=judgeState(str);
			linkfilter.setState(temp);
			
			
		}
		
		
	}
	
	
	public String getLinkAfterFilter(){//得到过滤后的链接。
		
		setState();//先设置状态。
		
		if(linkfilter.getState()==URLPASS){
			
			return linkfilter.getContent();
			
			}
		if(linkfilter.getState()==URLSTOP){
			
			return linkfilter.getContent();
			}
		
		if(linkfilter.getState()==URLFORBID){
			
			return null;
			}
		
		return null;
	}
	
	
	/**
	 * 
	 * 这个核心方法，如果添加另外一种过滤器的时候，只需要修改这个方法就可以了。
	 */
	private int judgeState(String str){//成功。
		
		
		String name=Thread.currentThread().getName();
		
        //AllLinksHashtable alltable = AllLinksHashtable.getInstance();// 获取全局URL的Hash表。
		//UnLinkHash untable=alltable.getun(name);//这个是不好的设计，将UrlPicker和该类耦合起来了。非常糟糕
		
		//到底为什么要设计UnLinkHash???
		
		 
		
		//System.out.println("contenttypeFilter正在判断该链接:"+str);
		
		HttpURLConnection uc=null;
		try {
			URL url = new URL (str);
			uc = (HttpURLConnection) url.openConnection ();
			
			uc.setConnectTimeout(5000);//设置连接超时。
			uc.setReadTimeout(5000);//设置读取数据超时。
			
			String contenttype= uc.getContentType();
			
			//System.out.println("数据类型："+contenttype);
			uc.connect ();
			
		}catch(SocketTimeoutException e){
			//untable.put(str);
			MyLogger.log("链接超时了:"+str);
			return URLFORBID;
			
		}catch (java.net.ConnectException e){
			
			 //untable.put(str);//这段代码让类之间形成了耦合，有时候代码之间的耦合是不知不觉的.
			 //这里如果连接不上URL的时候，这个链接将没有可下载性，返回null;
			 //System.out.println("URL不能进行链接："+str);
			 return URLFORBID;
		}
		catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			//untable.put(str);
			MyLogger.log("抛出MalformedURLException异常:"+str);
			
			 return URLFORBID;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//untable.put(str);
			MyLogger.log("抛出IOException异常:"+str);
			return URLFORBID;
		}
		
		uc.disconnect();
		
		String contenttype=uc.getContentType();

		//这个地方修改了一下。因为这个地方getContentType()并不规范，
		//它返回text/html;charset=UTF-8这些
		
		if((null!=contenttype)&&(contenttype.toLowerCase().indexOf("text/html")!=-1)){
					
			
			//System.out.println("contenttypeFilter通过该链接:"+str);
					return URLSTOP;
		 }
		
		//这个地方怎么没有答应出来。
		//untable.put(str);//这个地方也可以考虑一下这里要不要放str.
		//System.out.println("该URL不是网页(text/html):"+str);	 
		
		return URLFORBID;
	}
				
	public String getContent(){//在几个装饰器之间用这个函数传递。
		
		return getLinkAfterFilter();
	}
	
	//垃圾方法
	public int getState(){
		
		setState();
		
		return linkfilter.getState();//这个地方有点错。这个地方必须设置成反应后的啊
	}

  public void setState(int i){
  	
  	linkfilter.setState(i);
  }
  
  
  
  public static void main(String[] args) {

		String str = "http://www.cdut.edu.cn/cdut/cdut.cn";
		
		
		MyLink ml1=new MyLink(str);

	    PostfixFilter ml2=new PostfixFilter(ml1);
	    ContentTypeFilter ml3=new ContentTypeFilter(ml1);
	  	
	  	String str1=ml3.getLinkAfterFilter();
	  	
	  	
	  	System.out.println(str1);
		

	}
  
  
  
  
  
  
  
  
  

}
